package com.qiyu.mall.user.provider.service;


import com.alibaba.fastjson.JSON;
import com.qiyu.core.cache.redis.app.id.IdService;
import com.qiyu.core.cache.redis.client.IRedisService;
import com.qiyu.mall.user.interfaces.constants.MiniProgramConstants;
import com.qiyu.mall.user.interfaces.dto.*;
import com.qiyu.mall.user.provider.entity.WorkerPO;
import com.qiyu.mall.user.interfaces.service.AccountService;
import com.qiyu.mall.user.interfaces.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * 登录服务
 *
 * @author linhao
 * @date 2019/7/18
 * @Version V1.0
 */
@Service
@Slf4j
//todo 部分冲突仍未有解决
public class AuthServiceImpl implements AuthService {

    @Resource
    private IRedisService redisService;
    @Resource
    private IdService idService;
    @Resource
    private AccountService accountService;


    @Override
    public WorkerDTO getWorker(String workerToken) {
        WorkerPO workerPO = (WorkerPO) redisService.getObj(workerToken, WorkerPO.class);
        if (workerPO != null) {
            WorkerDTO workerDTO = new WorkerDTO();
            BeanUtils.copyProperties(workerPO, workerDTO);
            return workerDTO;
        }
        return null;
    }

    @Override
    public MiniProgramLoginDTO getWx3rdResponse(String code) {
        HashMap<String, String> params = new HashMap<>(4);
        params.put("appid", MiniProgramConstants.APPID);
        params.put("secret", MiniProgramConstants.APP_SECRET);
        params.put("js_code", code);
        params.put("grant_type", "authorization_code");
        HttpResponse response = HttpUtils.sendGet(MiniProgramConstants.GET_OPENID_URL, params);
        String result = null;
        try {
            result = EntityUtils.toString(response.getEntity(), "utf-8");
            log.info("【getWx3rdResponse】微信返回对象信息:{}", result);
            System.out.println(result);
            Wx3rdServerResponseDTO wx3rdServerResponseDTO = JSON.parseObject(result, Wx3rdServerResponseDTO.class);
            String openid;
            String sessionKey = wx3rdServerResponseDTO.getSession_key();
            if (MiniProgramConstants.TEST_OPENID2.equals(code)) {
                openid = MiniProgramConstants.TEST_OPENID2;
                wx3rdServerResponseDTO.setOpenid(openid);
            } else {
                openid = wx3rdServerResponseDTO.getOpenid();
            }
            AccountDTO accountDTO = accountService.getByOpenId(openid);
            if (accountDTO == null) {
                accountDTO = accountService.saveAccount("新人报道", openid);
            } else {
                accountService.updateLoginTime(openid);
            }
            MiniProgramLoginDTO miniProgramLoginDTO = new MiniProgramLoginDTO();
            Integer accountId = accountDTO.getAccountId();

            String token = this.createToken(openid, accountId, sessionKey);
            miniProgramLoginDTO.setToken(token);
            miniProgramLoginDTO.setAccountId(accountId);
            return miniProgramLoginDTO;
        } catch (IOException e) {
            log.error("【AuthServiceImpl.getWx3rdResponse】 出现异常，异常为{}", e);
        }
        return null;
    }


    @Override
    public String createToken(String openId, Integer accountId, String sessionKey) {
        String token = UUID.randomUUID().toString();
        LoginDTO loginDTO = LoginDTO.builder().openId(openId).accountId(accountId).sessionKey(sessionKey).build();
        redisService.setObj(RedisKeyUtil.buildToken(token), loginDTO, 60, TimeUnit.DAYS);
        System.out.println("【创建token】token信息为:" + RedisKeyUtil.buildToken(token));
        return token;
    }

    @Override
    public String getOpenIdFromToken(String token) {
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        LoginDTO loginDTO = (LoginDTO) redisService.getObj(RedisKeyUtil.buildToken(token), LoginDTO.class);
        return loginDTO != null ? loginDTO.getOpenId() : null;
    }

    @Override
    public String getSessionKeyFromToken(String token) {
        LoginDTO loginDTO = (LoginDTO) redisService.getObj(RedisKeyUtil.buildToken(token), LoginDTO.class);
        return loginDTO.getSessionKey();
    }


    @Override
    public LoginDTO checkToken(String token) {
        if (MiniProgramConstants.TEST_TOKEN.equals(token)) {
            return new LoginDTO(MiniProgramConstants.TEST_OPENID, MiniProgramConstants.TEST_MEMBERID, MiniProgramConstants.TEST_SESSION_KEY);
        }
        return (LoginDTO) redisService.getObj(RedisKeyUtil.buildToken(token), LoginDTO.class);
    }

}
